home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
351-375
/
disk_354
/
keymacro
/
keymacro.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
15KB
|
802 lines
/****************************************************************************
*
* KeyMacro.c ------------ KeyMacro main process.
*
* Author ---------------- Olaf Barthel, MXM
* Brabeckstrasse 35
* D-3000 Hannover 71
*
* KeyMacro © Copyright 1990 by MXM; Executable program,
* documentation and source code are shareware. If you like
* this program a small donation will entitle you to receive
* updates and new programs from MXM.
*
****************************************************************************/
#include <libraries/arpbase.h>
/* Function prototypes. */
VOID * SendMacroMsg(struct MacroMessage *);
UBYTE * GetToken(UBYTE *,LONG *);
struct MacroKey * AddMacroKey(struct MacroKey *);
LONG Interprete(UBYTE *,LONG);
LONG UpdateList(char *);
VOID main(LONG,char **);
/* The Arp CLI-Interface data. */
char *CLI_Template = "STARTUP/K,QUIT/S,INFO/S";
char *CLI_Help = "\nUsage: \33[1mKeyMacro\33[0m [STARTUP <File>] [QUIT] [INFO]\n";
#define ARG_STARTUP 1
#define ARG_QUIT 2
#define ARG_INFO 3
#define ARG_UPDATE 4
/* Easy macro. */
#define From_CLI (ThatsMe -> pr_CLI)
/* Global and shared data structures. */
struct MXMBase *MXMBase;
extern struct ArpBase *ArpBase;
struct MSeg *MSeg;
struct MacroKey *KeyList;
extern struct ExecBase *SysBase;
/* We use this list to identify the non-ascii keys. */
struct KeyAlias KeyTab[22] =
{
{"TAB", 0x42},
{"ESC", 0x45},
{"SPACE", 0x40},
{"RETURN", 0x44},
{"ENTER", 0x43},
{"DEL", 0x46},
{"BACKSPACE", 0x41},
{"HELP", 0x5F},
{"LEFT", 0x4F},
{"RIGHT", 0x4E},
{"UP", 0x4C},
{"DOWN", 0x4D},
{"F1", 0x50},
{"F2", 0x51},
{"F3", 0x52},
{"F4", 0x53},
{"F5", 0x54},
{"F6", 0x55},
{"F7", 0x56},
{"F8", 0x57},
{"F9", 0x58},
{"F10", 0x59}
};
/* These are the qualifiers. */
struct KeyAlias QualifierTab[9] =
{
{"NONE", 0},
{"CTRL", IEQUALIFIER_CONTROL},
{"NUMPAD", IEQUALIFIER_NUMERICPAD},
{"LSHIFT", IEQUALIFIER_LSHIFT},
{"RSHIFT", IEQUALIFIER_RSHIFT},
{"LALT", IEQUALIFIER_LALT},
{"RALT", IEQUALIFIER_RALT},
{"LAMIGA", IEQUALIFIER_LCOMMAND},
{"RAMIGA", IEQUALIFIER_RCOMMAND}
};
/* SendMacroMsg(scm_Msg,scm_Port):
*
* Post a cloned macro message to a MsgPort.
*/
VOID *
SendMacroMsg(struct MacroMessage *scm_Msg)
{
struct MacroMessage *scm_TempMsg = (struct MacroMessage *)AllocRem(sizeof(struct MacroMessage),MEMF_PUBLIC | MEMF_CLEAR);
if(scm_TempMsg)
{
CopyMem(scm_Msg,scm_TempMsg,sizeof(struct MacroMessage));
scm_TempMsg -> mm_Message . mn_Node . ln_Name = (char *)scm_TempMsg;
scm_TempMsg -> mm_Message . mn_ReplyPort = NULL;
scm_TempMsg -> mm_Message . mn_Length = sizeof(struct MacroMessage);
PutMsg(&MSeg -> Port,(struct Message *)scm_TempMsg);
}
return((VOID *)scm_TempMsg);
}
/* GetToken(s,start):
*
* Parse a string and split it into single tokens.
*/
UBYTE *
GetToken(UBYTE *s,LONG *start)
{
static UBYTE buffer[256];
LONG i,end = 0,quote = FALSE,maxlen = strlen(s);
char t;
if(maxlen > 255)
maxlen = 255;
if(*start > strlen(s) - 1 || !strlen(s) || !s)
return(NULL);
for(i = *start ; i <= maxlen ; i++)
{
if(!end && (s[i] == ' ' || s[i] == '\t'))
{
while((s[i] == ' ' || s[i] == '\t') && i < maxlen)
{
i++;
(*start)++;
}
}
t = s[i];
if(!end && t == '+')
{
(*start)++;
continue;
}
if(!end && t == '=')
{
strcpy(buffer,"=");
(*start)++;
return(buffer);
}
if(s[i] == '\\' && s[i + 1] == '\"')
{
i += 2;
end = i - *start + 1;
t = s[i];
}
if(t == '\"' && !quote)
{
quote = TRUE;
(*start)++;
end++;
continue;
}
if((t == '+' || t == '=' || t == ' ' || t == '\t' || t == ';') && quote)
{
end++;
continue;
}
if((t == '+' || t == '\n' || t == '=' || t == ' ' || t == 0) || (t == '\"' && quote) || (t == ';' && !quote))
{
if(t == ';' && !end)
return(NULL);
if(t == '\"')
{
strncpy(buffer,s + *start,end - 1);
buffer[end - 1] = 0;
}
else
{
strncpy(buffer,s + *start,end);
buffer[end] = 0;
}
(*start) += end;
return(buffer);
}
end++;
}
return(NULL);
}
/* AddMacroKey(MacroKey):
*
* Add a macro key to the big list.
*/
struct MacroKey *
AddMacroKey(struct MacroKey *MacroKey)
{
struct MacroKey *TheKey = NULL;
LONG i;
for(i = 0 ; i < MSeg -> NumMacros ; i++)
{
if(KeyList[i] . mk_Type == MK_UNUSED)
{
TheKey = &KeyList[i];
break;
}
}
if(!TheKey)
return(NULL);
CopyMem(MacroKey,TheKey,sizeof(struct MacroKey));
return(TheKey);
}
/* Interprete(String,Line):
*
* Interprete a command line from the config file.
*/
LONG
Interprete(UBYTE *String,LONG Line)
{
ULONG Qualifier = 0;
ULONG Code = -1;
struct InputEvent FakeEvent;
struct MacroKey NewKey;
LONG Start = 0,Key = FALSE,i,KeyCount = 0;
volatile LONG QuitLoop;
UBYTE *Token,*CommandString,*WindowName = NULL,Recognized = FALSE;
UBYTE MessBuff[256],KeyBuff1[40],KeyBuff2[40];
if(String[strlen(String) - 1] == '\n')
String[strlen(String) - 1] = 0;
if(Token = GetToken(String,&Start))
{
if(!UStrCmp("KEY",Token))
Key = TRUE;
if(UStrCmp("COMMAND",Token) && !Key)
{
SPrintf(MessBuff,"Line %ld: Unknown keyword:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
}
else
return(TRUE);
FOREVER
{
if(Token = GetToken(String,&Start))
{
QuitLoop = TRUE;
for(i = 0 ; i < 9 ; i++)
{
if(!UStrCmp(QualifierTab[i] . ka_Name,Token))
{
Recognized = TRUE;
QuitLoop = FALSE;
Qualifier |= QualifierTab[i] . ka_Key;
}
}
}
else
break;
if(QuitLoop)
break;
}
if(!Recognized)
{
SPrintf(MessBuff,"Line %ld: Didn't recognize qualifier:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
if(Token)
goto JumpIn;
if(Token = GetToken(String,&Start))
{
JumpIn: for(i = 0 ; i < 22 ; i++)
{
if(!UStrCmp(KeyTab[i] . ka_Name,Token))
{
Code = KeyTab[i] . ka_Key;
goto Next;
}
}
if(InvertKey(Token[0],&FakeEvent,IK_USEIKM,NULL))
Code = FakeEvent . ie_Code;
}
if(Code == -1)
{
SPrintf(MessBuff,"Line %ld: Didn't recognize key:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
Next: FOREVER
{
if(Token = GetToken(String,&Start))
{
if(!UStrCmp("=",Token))
break;
}
else
{
SPrintf(MessBuff,"Line %ld: Statement '=' missing:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
}
if(Token = GetToken(String,&Start))
strcpy(KeyBuff1,Token);
else
{
SPrintf(MessBuff,"Line %ld: Didn't find macro:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
if(Key)
goto AddIt;
if(!(Token = GetToken(String,&Start)))
goto AddIt;
if(UStrCmp("WINDOW",Token))
{
SPrintf(MessBuff,"Line %ld: Didn't recognize 'WINDOW' statement:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
if(!(Token = GetToken(String,&Start)))
{
SPrintf(MessBuff,"Line %ld: Didn't find window title:\n\n'%s'",Line,String);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
if(!(WindowName = (UBYTE *)AllocRem(strlen(Token) + 1,MEMF_PUBLIC)))
{
PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
strcpy(WindowName,Token);
AddIt: for(i = 0 ; i < strlen(KeyBuff1) ; i++)
{
UBYTE c;
if(KeyBuff1[i] != '\\')
{
KeyBuff2[KeyCount++] = KeyBuff1[i];
continue;
}
if(i == strlen(KeyBuff1) - 1)
break;
i++;
c = 0;
switch(ToUpper(KeyBuff1[i]))
{
case 'U': c = KC_CURSORUP;
break;
case 'D': c = KC_CURSORDOWN;
break;
case 'L': c = KC_CURSORLEFT;
break;
case 'R': c = KC_CURSORRIGHT;
break;
case 'H': c = KC_HELP;
break;
case 'B': c = 8;
break;
case 'E': c = 127;
break;
case 'F': if(i == strlen(KeyBuff1) - 1)
break;
i++;
if(!isdigit(KeyBuff1[i]))
break;
if(!KeyBuff1[i] == '1')
{
c = KC_FKEY1 + KeyBuff1[i] - '1';
break;
}
if(i == strlen(KeyBuff1) - 1)
break;
i++;
if(!isdigit(KeyBuff1[i]))
{
c = KC_FKEY1;
break;
}
if(KeyBuff1[i] != '0')
break;
c = KC_FKEY10;
break;
case 'N': c = '\n';
break;
case '\\': c = '\\';
break;
default: c = KeyBuff1[i];
break;
}
if(c)
KeyBuff2[KeyCount++] = c;
}
KeyBuff2[KeyCount] = 0;
if(!(CommandString = (UBYTE *)AllocRem(strlen(KeyBuff2) + 1,MEMF_PUBLIC)))
{
PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
FreeRem(WindowName);
return(FALSE);
}
strcpy(CommandString,KeyBuff2);
memset(&NewKey,0,sizeof(struct MacroKey));
NewKey . mk_CommandKey = Code;
NewKey . mk_CommandQualifier = Qualifier;
NewKey . mk_String = CommandString;
NewKey . mk_Window = WindowName;
if(Key)
NewKey . mk_Type = MK_WORD;
else
NewKey . mk_Type = MK_COMMAND;
if(AddMacroKey(&NewKey))
return(TRUE);
SPrintf(MessBuff,"Line %ld: Key macro table full.",Line);
PopRequest(NULL,"KeyMacro Problem:",MessBuff,NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
/* UpdateList(Name):
*
* Update the big macro key list.
*/
LONG
UpdateList(char *Name)
{
char LineBuff[256];
LONG LineNum = 1;
FILE *ConfigFile;
if(!Name)
Name = "S:KeyMacro.config";
if(!(KeyList = (struct MacroKey *)AllocRem(sizeof(struct MacroKey) * MAXMACROS,MEMF_PUBLIC | MEMF_CLEAR)))
{
PopRequest(NULL,"KeyMacro Problem:","Can't allocate memory chunk!",NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
MSeg -> NumMacros = MAXMACROS;
if(ConfigFile = fopen(Name,"r"))
{
while(fgets(LineBuff,256,ConfigFile))
{
if(!Interprete(LineBuff,LineNum++))
{
fclose(ConfigFile);
FreeRem(KeyList);
return(FALSE);
}
}
fclose(ConfigFile);
}
else
{
PopRequest(NULL,"KeyMacro Problem:","Couldn't open configuration file!",NULL,"Continue?",FALSE,NULL);
return(FALSE);
}
return(TRUE);
}
/* main(argc,argv):
*
* The entry point to this program.
*/
VOID
main(LONG argc,char **argv)
{
struct Process *ThatsMe = (struct Process *)SysBase -> ThisTask;
LONG Created = FALSE;
char *FileName = argv[ARG_STARTUP];
LONG i;
/* No ^C trapping, please. */
Enable_Abort = FALSE;
/* Started from Workbench? */
if(!From_CLI)
FileName = NULL;
/* Try to open mxm.library. */
if(!(MXMBase = (struct MXMBase *)OpenLibrary("mxm.library",34)))
{
if(From_CLI)
Puts("\33[1mKeyMacro:\33[0m You need \33[1mmxm.library\33[0m 34.12 or higher to run this program.");
exit(RETURN_FAIL);
}
/* Look if handler process is already running. */
MSeg = (struct MSeg *)FindPort(PORTNAME);
/* Short info? */
if(argv[ARG_INFO])
{
Printf("\n\33[1m\33[33mKeyMacro\33[31m\33[0m the Amiga macro key handler.\n\n");
Printf(" This program may be non-commercially\n");
Printf(" redistributed!\n\n");
Printf("\33[1m\33[33mAuthor\33[31m\33[0m - Olaf Barthel, MXM\n");
Printf(" Brabeckstrasse 35\n");
Printf(" D-3000 Hannover 71\n\n");
Printf(" Federal Republic of Germany.\n\n");
CloseLibrary((struct Library *)MXMBase);
exit(RETURN_OK);
}
/* Remove the handler? */
if(argv[ARG_QUIT])
{
Printf("Removing \33[1m\33[33mKeyMacro\33[31m\33[0m, ");
if(!MSeg)
{
Printf("failed!\7\n");
CloseLibrary((struct Library *)MXMBase);
exit(RETURN_OK);
}
MSeg -> Father = (struct Task *)SysBase -> ThisTask;
if(MSeg -> Child)
{
Signal(MSeg -> Child,SIG_CLOSE);
Wait(SIG_CLOSE);
}
RemPort((struct MsgPort *)MSeg);
FreeMem(MSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME));
if(MSeg -> Segment)
UnLoadPrg(MSeg -> Segment);
if(MSeg -> MacroList)
{
for(i = 0 ; i < MSeg -> NumMacros ; i++)
{
if(MSeg -> MacroList[i] . mk_Type == MK_UNUSED)
continue;
if(MSeg -> MacroList[i] . mk_String)
FreeRem(MSeg -> MacroList[i] . mk_String);
if(MSeg -> MacroList[i] . mk_Window)
FreeRem(MSeg -> MacroList[i] . mk_Window);
}
FreeRem(MSeg -> MacroList);
}
FreeRem(MSeg);
Printf("OK.\n");
CloseLibrary((struct Library *)MXMBase);
exit(RETURN_OK);
}
/* Allocate the handler data. */
if(!MSeg)
{
if(MSeg = (struct MSeg *)AllocRem(sizeof(struct MSeg),MEMF_PUBLIC | MEMF_CLEAR))
{
MSeg -> Port . mp_Flags = PA_IGNORE;
MSeg -> Port . mp_Node . ln_Pri = 0;
MSeg -> Port . mp_Node . ln_Type = NT_MSGPORT;
MSeg -> Port . mp_Node . ln_Name = AllocMem(sizeof(PORTNAME),MEMF_PUBLIC);
MSeg -> Child = NULL;
MSeg -> Father = (struct Task *)SysBase -> ThisTask;
MSeg -> SegSize = sizeof(struct MSeg);
MSeg -> RingBack = SIGBREAKF_CTRL_C;
MSeg -> Revision = REVISION;
NewList(&MSeg -> Port . mp_MsgList);
if(From_CLI)
{
Printf("\33[1m\33[33mKeyMacro v1.%ld \33[31m\33[0m(C) Copyright 1989, 1990 by \33[4mMXM\33[0m.\n",REVISION);
Printf("Installing \33[33m\33[1mKeyMacro\33[0m\33[31m, ");
}
if(MSeg -> Port . mp_Node . ln_Name)
strcpy(MSeg -> Port . mp_Node . ln_Name,PORTNAME);
else
{
if(From_CLI)
Printf("failed!\n");
CloseLibrary((struct Library *)MXMBase);
exit(RETURN_FAIL);
}
MSeg -> Segment = LoadPrg("KeyMacro-Handler");
if(!MSeg -> Segment)
MSeg -> Segment = LoadPrg("L:KeyMacro-Handler");
if(!MSeg -> Segment)
{
if(From_CLI)
Printf("unable to find \33[33mL:KeyMacro-Handler\33[31m\7!\n");
FreeRem(MSeg -> Port . mp_Node . ln_Name);
FreeRem(MSeg);
}
else
{
AddPort((struct MsgPort *)MSeg);
if(!CreateProc("KeyMacro-Handler",10,MSeg -> Segment,4096))
goto NoMem;
Wait(SIGBREAKF_CTRL_C);
if(!MSeg -> Child)
{
NoMem: if(From_CLI)
Printf("\33[33mFAILED!\33[31m (care to retry?)\n");
RemPort((struct MsgPort *)MSeg);
FreeRem(MSeg -> Port . mp_Node . ln_Name);
if(MSeg -> Segment)
UnLoadPrg(MSeg -> Segment);
FreeRem(MSeg);
CloseLibrary((struct Library *)MXMBase);
exit(RETURN_FAIL);
}
else
{
if(From_CLI)
Printf("initializing, ");
InvertKey(NULL,NULL,IK_USEIKM | IK_BUILDLIST,NULL);
if(From_CLI)
Puts("Okay.");
else
PopRequest(NULL,"KeyMacro Info:","\33[1mKeyMacro\33[0m installed.",NULL,"Continue?",FALSE,NULL);
Created = TRUE;
}
}
}
}
/* Update the macro key list. */
if(UpdateList(FileName))
{
if(Created)
{
MSeg -> NumMacros = MAXMACROS;
MSeg -> MacroList = KeyList;
}
else
{
struct MacroMessage UpdateMsg;
UpdateMsg . mm_Type = MM_UPDATE;
UpdateMsg . mm_NumMacros= MAXMACROS;
UpdateMsg . mm_MacroList= KeyList;
SendMacroMsg(&UpdateMsg);
if(From_CLI)
Printf("\33[1mKeyMacro:\33[0m Updating macro keys...\n");
}
}
else
{
CloseLibrary((struct Library *)MXMBase);
exit(RETURN_ERROR);
}
CloseLibrary((struct Library *)MXMBase);
exit(RETURN_OK);
}